package com.slofzx.nuoda.evaluation.project.builder;

import com.slofzx.nuoda.common.util.DataConvertUtil;
import com.slofzx.nuoda.custom.template.enums.SumTypeEnum;
import com.slofzx.nuoda.evaluation.project.compont.CopyExcelComponent;
import com.slofzx.nuoda.evaluation.project.util.BusiUtil;
import com.slofzx.nuoda.evaluation.project.util.ExcelOperateUtil;
import com.slofzx.nuoda.excel.builder.AbstractExcelBuilder;
import com.slofzx.nuoda.excel.entity.CellConfig;
import com.slofzx.nuoda.excel.entity.SheetConfig;
import com.slofzx.nuoda.excel.entity.TemplateConfig;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;

import java.util.*;

/**
 * excel导出按列写入构造器
 */
public abstract class AbstractVerticalExcelBuilder extends AbstractExcelBuilder {
    private CopyExcelComponent copyExcelComponent;

    public AbstractVerticalExcelBuilder(TemplateConfig config, CopyExcelComponent copyExcelComponent) {
        super(config);
        this.copyExcelComponent = new CopyExcelComponent();
    }

    @Override
    public Workbook build() {
        return this.build(this.getSheetDataMap());
    }

    @Override
    public Workbook build(Map<String, List<Map<String, Object>>> sheetDataMap) {
        // todo 尚未处理合并单元格
        try {
            this.buildWorkbook();
            Workbook workbook = super.workbook;
            List<SheetConfig> sheetConfigList = super.templateConfig.getSheetConfigList();
            cellStyleCacheMap.clear();
            for (SheetConfig sheetConfig : sheetConfigList) {
                Sheet sheet = workbook.getSheet(sheetConfig.getName());
                if (sheet == null) {
                    sheet = workbook.createSheet(sheetConfig.getName());
                    copyExcelComponent.copySheet(this.workbook, this.workbook, workbook.getSheetAt(0), sheet);
                }
                // 获取年份数据
                final List<Map<String, Object>> dataMapList = sheetDataMap.get(sheetConfig.getName());
                if (CollectionUtils.isEmpty(dataMapList)) {
                    continue;
                }
                Set<CellConfig> singleDataCellSet = new HashSet();
                // 获取单个数据
                final Map<String, Object> singleDataMap = getSingleDataMap(sheetConfig);
                final List<CellConfig> cellConfigList = sheetConfig.getCellConfigList();
                // 获取单个数据配置
                if (sheetConfig.getCellConfigList() != null && singleDataMap != null && !singleDataMap.isEmpty()) {
                    for (CellConfig cellConfig : cellConfigList) {
                        if (singleDataMap.get(cellConfig.getData()) != null) {
                            singleDataCellSet.add(cellConfig);
                        }
                    }
                }


                for (CellConfig cellConfig : cellConfigList) {
                    final Row row = sheet.getRow(cellConfig.getRowIndex() - 1);
                    final Cell cell = row.getCell(cellConfig.getColIndex() - 1);
                    if (cell != null && cell.getCellType() == CellType.STRING) {
                        String text = cell.getStringCellValue();
                        if ("$".equals(text)) {
                            cell.setCellValue("");
                        } else if (StringUtils.isNotEmpty(text) && super.paramMap != null) {
                            Iterator var15 = super.paramMap.entrySet().iterator();

                            while (var15.hasNext()) {
                                Map.Entry<String, String> entry = (Map.Entry) var15.next();
                                String key = "${" + (String) entry.getKey() + "}";
                                if (text.contains(key)) {
                                    String dataType = entry.getValue() == null ? "" : (String) entry.getValue();
                                    text = text.replace(key, dataType);
                                    cell.setCellValue(text);
                                }
                            }
                        }
                    }

                }
                Map<String, List<Double>> sumDataMap = new HashMap<>();
                boolean hasSumType = false;
                // 写入年份数据非合计数据
                for (CellConfig cellConfig : cellConfigList) {

                    final int rowIndex = cellConfig.getRowIndex() - 1;
                    int colIndex = cellConfig.getColIndex() -1;
                    final Row row = sheet.getRow(rowIndex);
                    if (StringUtils.isEmpty(cellConfig.getData())) {
                        final Cell fromCell = row.getCell(colIndex);
                        // 获取单元格样式
                        CellStyle copyCellStyle = getCellStyle(workbook, cellConfig, fromCell);
                        for (int i = 0; i < dataMapList.size(); i++) {
                            final Cell newCell = row.createCell(colIndex + i);
                            // 如果是年份则需要处理标题
                            final int columnIndex = newCell.getColumnIndex();

                            if (cellConfig.getDataType().equals("year")) {
                                newCell.setCellStyle(copyCellStyle);
                                updateStringCell(null, row, columnIndex, "第" + (i + 1) + "年");
                            } else {
                                newCell.setCellStyle(copyCellStyle);
                            }
                        }

                        continue;
                    }
                    // 单个值处理设置数据
                    final String key = cellConfig.getData();
                    if (singleDataCellSet.contains(cellConfig)) {
                        updateCell(null, row, colIndex, singleDataMap.get(key), cellConfig.getDigit());
                        continue;
                    }
                    // 年份数据
                    SumTypeEnum sumTypeEnum = SumTypeEnum.getEnum(cellConfig.getSumType());
                    final Cell fromCell = row.getCell(colIndex - 1);
//                    int copyStyleCol = colIndex;
//                    if (key.equals("year")) {
//                        copyStyleCol =  copyStyleCol +1;
//                    }
//                    final Cell fromCell1 = row.getCell(copyStyleCol);
                    final CellStyle copyYearCellStyle =getCellStyle(workbook,cellConfig,fromCell);
                     CellStyle copyCellStyle =null;
                    for (int i = 0; i < dataMapList.size(); i++) {
                        Cell newCell;
                        if (i==0) {
                            newCell = row.getCell(colIndex);
                            copyCellStyle = newCell.getCellStyle();
                        } else {
                            newCell = row.createCell(colIndex + i);
                        }

                        final Map<String, Object> dataMap = dataMapList.get(i);
                        // 如果是年份则需要处理标题
                        final int columnIndex = newCell.getColumnIndex();
                        Object data = dataMap.get(key);
                        // 复制单元格样式
                        if (key.equals("year")) {
                            updateStringCell(null, row, columnIndex,  data + "");
                            newCell.setCellStyle(copyYearCellStyle);
                        } else {
                            // 当前配置有合计类型则加入合计map
                            if (sumTypeEnum != null) {
                                hasSumType = true;
                                if (data instanceof Number) {
                                    final String sumDataKey = getConfigKey(cellConfig);
                                    List<Double> list = sumDataMap.get(sumDataKey);
                                    if (CollectionUtils.isEmpty(list)) {
                                        list = new ArrayList<>();
                                        sumDataMap.put(sumDataKey, list);
                                    }
                                    list.add(DataConvertUtil.parse2Double(data));
                                }
                            }
                            // sumCell = newCell;
                            // 写入数据

                            updateCell(null, row, columnIndex, data, cellConfig.getDigit());
                            newCell.setCellStyle(copyCellStyle);
                        }


                    }

                }
                // 如果合计数据对象不为空写入合计数据
                if (MapUtils.isNotEmpty(sumDataMap)) {
                    for (CellConfig config : cellConfigList) {
                        SumTypeEnum sumTypeEnum = SumTypeEnum.getEnum(config.getSumType());
                        // 年份数据
                        if (singleDataCellSet.contains(config)) {
                            continue;
                        }
                        final Row row = sheet.getRow(config.getRowIndex() - 1);
                        final int colIndex = config.getColIndex() - 1;

                        // 获取后一个单元格用于复制样式
                       // final Cell oldCell = row.getCell(colIndex - 1);
                        if ("year".equals(config.getData()) || "year".equals(config.getDataType())) {
                            if (hasSumType) {
                                //从第一年开始所有单元格往后移动一格
                                row.shiftCellsRight(colIndex, row.getLastCellNum(), 1);
                                updateStringCell(null, row, colIndex, "合计");
                            }


                        } else {
                            if (hasSumType) {
                                row.shiftCellsRight(colIndex, row.getLastCellNum(), 1);
                            }
                            final List<Double> list = sumDataMap.get(getConfigKey(config));
                            Double sumData = 0D;
                            if (sumTypeEnum != null && CollectionUtils.isNotEmpty(list)) {

                                switch (sumTypeEnum) {
                                    case SUM:
                                        sumData = list.stream().mapToDouble(m -> m).sum();
                                        break;
                                    case AVG:
                                        sumData = list.stream().mapToDouble(m -> m).average().getAsDouble();
                                        break;
                                    case MAX:
                                        sumData = list.stream().mapToDouble(m -> m).max().getAsDouble();
                                        break;
                                    case MIN:
                                        sumData = list.stream().mapToDouble(m -> m).min().getAsDouble();
                                        break;
                                }
                            }
                            String sumDataStr = sumData == 0 ? StringUtils.EMPTY : sumData.toString();
                            updateCell(null, row, colIndex, sumDataStr, config.getDigit());

                        }
                        if (hasSumType) {
                            final Cell cell = row.getCell(colIndex + 2);
                            final CellStyle cellStyle = copyExcelComponent.getCopyCellStyle(workbook,workbook,cell.getCellStyle());
                            row.getCell(colIndex).setCellStyle(cellStyle);
                        }

                    }
                }
            }
             workbook.removeSheetAt(0);
            return workbook;
        } catch (Exception var38) {
            super.logger.error("生成excel数据异常", var38);
            return super.workbook;
        }
    }

    /**
     * 根据指定样式生成一个样式
     * @param workbook
     * @param cellConfig
     * @param fromCell
     * @return
     */
    private CellStyle getCellStyle(Workbook workbook, CellConfig cellConfig, Cell fromCell) {
        final String sumDataKey = getConfigKey(cellConfig);
         CellStyle cellStyle = cellStyleCacheMap.get(sumDataKey);
        if (cellStyle == null) {
            cellStyle = copyExcelComponent.getCopyCellStyle(workbook,workbook,fromCell.getCellStyle());
            cellStyleCacheMap.put(sumDataKey,cellStyle);
        }
        return cellStyle;
    }

    /**
     * 根据单元格配置生成一个key值
     * @param cellConfig
     * @return
     */
    private String getConfigKey(CellConfig cellConfig) {
        return BusiUtil.generateBusiKey(String.valueOf(cellConfig.getRowIndex()), String.valueOf(cellConfig.getColIndex()));
    }
}
